/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* 
 * File:   bcos_pcb.h
 * Author: bluce
 *
 * Created on 2021年2月28日, 上午11:50
 */

#ifndef BCOS_PCB_H
#define BCOS_PCB_H

#include <stdint.h>

#include "list.h"
#include "bcos_asm.h"
#include "bcos_mem.h"

#define  BCOS_LOWER_MODE_SUPPORT				0
#if BCOS_LOWER_MODE_SUPPORT
#define  BCOS_MINI_SLEEP_TICKS					2
#endif

#define  BCOS_FREE_TASK_PRO						0xFF
#define  BCOS_MAINLOOP_TASK_PRO					0xFE

#define  BCOS_FREE_STK_SIZE						80
#define  BCOS_MAINLOOP_STK_SIZE                 1024


#define  OS_ENTER_CRITICAL()  {cpu_sr = OS_CPU_SR_Save();}
#define  OS_EXIT_CRITICAL()   {OS_CPU_SR_Restore(cpu_sr);}

static inline int bcos_irq_lock(void)
{
    return OS_CPU_SR_Save();
}

static inline void bcos_irq_unlock(int key)
{
    OS_CPU_SR_Restore(key);
}

#ifdef __cplusplus
extern "C" {
#endif

//type define
typedef unsigned int BC_OS_STK;
typedef uint64_t     BC_OS_TICK;
	

typedef struct bcos_tasklet_s
{
    /* 链表头 */
    struct list_head list;
	 
    /* 回调函数 */
    void (*handler)(void *ptr);
	/* 任务参数 */
    void *ptr;

	/* 任务延时间戳 */
    BC_OS_TICK  stamp;
}bcos_tasklet_t;


typedef struct bcos_tcb_s {
    /* Pointer to current top of stack */
    BC_OS_STK       *OSTCBStkPtr;
    /* 链表头 */ 
    struct list_head list;
    /* 优先级 */
    uint8_t          priority;
    /* 延时时间戳 */   
    BC_OS_TICK       delay_stamp;
    /* 任务栈顶部边界指针，动态分配栈时该指针不为空 */
	BC_OS_STK		 *OSTCBStkTopPtr;
} bcos_tcb_t;

/* 静态初始化任务TCB */
#define BCOS_TCB_STATIC_INIT(name, prio) 				\
{														\
    NULL,												\
    LIST_HEAD_INIT(name.list),							\
    prio,												\
    0,													\
	NULL,												\
}

/* 静态初始化tasklet */
#define BCOS_TASKLET_STATIC_INIT(name, handler, ptr) 	\
{ 														\
	LIST_HEAD_INIT(name.list),							\
	handler, 											\
	ptr, 												\
	0, 													\
}

extern  uint8_t            OSRunning;

extern  bcos_tcb_t           *OSTCBCur;
extern  bcos_tcb_t           *OSTCBHighRdy;

extern struct list_head     bcos_tcb_head;
extern struct list_head	 bcos_waiting_tcb_head;

#define BCOS_MINI(a, b) ((a < b)? a:b)

void bcos_task_create(bcos_tcb_t *tcb, void (*task)(void *ptr), void *p_arg, BC_OS_STK *ptos);
bcos_tcb_t *bcos_task_malloc(void (*task)(void *ptr), void *p_arg, uint8_t prio, uint16_t stack_size);
void bcos_task_destroy(bcos_tcb_t *tcb);

void bcos_tasklet_post(bcos_tasklet_t *tasklet, BC_OS_TICK ms);
void bcos_tasklet_cancel(bcos_tasklet_t *tasklet);

void bcos_scheduing(void);

void mainloop(void *ptr);

void bcos_delay_ms(BC_OS_TICK tick);

#if BCOS_LOWER_MODE_SUPPORT
void bcos_lowpower_enter_and_ticks_recovery(BC_OS_TICK sleep_ticks, BC_OS_TICK *os_ticks);
#endif

#ifdef __cplusplus
}
#endif

#endif /* BCOS_PCB_H */

